<template>
  <div v-if="ishowButton || showList.length > 0">
    <ul class="upload-box">
      <li v-for="(item, index) in showList" :key="item.url" class="upload-list__item" :style="{ width: size + 'px', height: size + 'px', lineHeight: size + 'px' }">
        <span class="upload-list__item-actions" :style="{ width: size + 'px', height: size + 'px', lineHeight: size + 'px' }">
          <i v-if="item.isimage" class="el-icon-view" @click="viewImg(item.imgurl, item, index)" />
          <i class="el-icon-download" @click="downLoad(item.imgurl, item.fileName)" />
          <i v-if="ishowButton" class="el-icon-delete" @click="delFile(item, item.fileName, index)" />
        </span>
        <el-progress
          v-if="item.f_status"
          :type="'circle'"
          :width="size"
          :stroke-width="6"
          :status="item.f_status === 'uploading' ? null : item.f_status"
          :percentage="parsePercentage(item.percentage, item.f_status)"
        />
        <template v-else>
          <el-image v-if="item.isimage" :src="item.imgurl" :fit="'contain'" :style="{ width: size + 'px', height: size + 'px' }"/>
          <span v-else class="upload-list__item-box">
            <el-image v-if="!item.icon" :src="item.imgurl" :fit="'contain'" :style="{ width: size + 'px', height: size + 'px' }" />
            <svg v-else class="fileicon" aria-hidden="true">
              <use :xlink:href="'#' + item.icon" />
            </svg>
          </span>
        </template>
      </li>
      <li v-if="ishowButton" class="upload-list__item" :style="{ width: size + 'px', height: size + 'px', lineHeight: size + 'px' }">
        <el-upload
          ref="upload"
          :action="action"
          name="file"
          multiple
          accept=".gif, .jpg, .jpeg, .png, .bmp, .GIF, .JPG, .PNG, .rar, .zip, .txt, .pdf, .word, .PDF, .xls, .docx"
          class="upload-button"
          :limit="limit"
          :before-upload="handleBeforeUpLoad"
          :http-request="uploadRequest"
          :file-list="fileList"
          :show-file-list="false"
          :on-exceed="handleExceed"
        >
          <slot>
            <div class="upload-icon">
              <span class="el-icon-plus" />
            </div>
          </slot>
        </el-upload>
      </li>
    </ul>

    <el-image-viewer v-if="dialogViewFileImg" :on-close="closeViewer" :z-index="19940306" :url-list="viewerImgList" />
  </div>
</template>
<script>
/**
 * 附件列表组件
 * @param {Array} value 组件列表的值
 * @param {Number} fileSize 文件
 * @param {Boolean} ishowButton 是否展示上传按钮
 */
import { parseTime } from '@/utils'
import axios from 'axios'
import handle from './handleCard.js'
//  GOODS("商品"), CONTENT("内容"), CATEGORY("类别"), SUPPLIER("供应商"), AVATAR("头像"), SYSTEM("系统"), OTHERS("其他"), CHAT("聊天"), LIVE("直播");
// 上传文件组件
export default {
  mixins: [handle],
  props: {
    // 上传数量
    limit: {
      type: Number,
      default: 100
    }
  },
  data() {
    return {
      viewerImgList: [],
      showList: [],
      initialIndex: 0,
      dialogViewFileImg: false,
      uidsObj: {}
    }
  },
  methods: {
    handleFileSuccess(res, file) {
      var t = file.type.indexOf('image') !== -1
      this.fileList = [
        ...this.fileList,
        {
          uid: file.uid,
          filePath: res.data,
          fileName: file.name,
          creater: this.$store.state.user.name,
          createTime: parseTime(new Date(), '{y}{m}{d}'),
          fileSize: this.readFileSizeUnit(file.size),
          type: file.type,
          isimage: t,
          imgurl: res.data,
          icon: t ? '' : this.setFileIcon(file)
        }
      ]
      this.$emit('input', this.fileList)
      this.$emit('change', this.fileList)
    },
    handleExceed(files, fileList) {
      this.$message.warning(`当前限制选择 ${this.limit} 个文件`)
    },
    /* 查看附件 */
    viewImg(url, item, index) {
      if (this.isImage(url) || item.isimage) {
        this.dialogViewFileImg = true
        this.initialIndex = index
        // this.viewerImgList = this.fileList.map((f) => {
        //   return f.imgurl
        // })
        this.fileList.map(f => {
          this.viewerImgList.push(f.imgurl)
          if (index === this.initialIndex) {
            this.viewerImgList[0] = url
          }
        })
      } else {
        window.open('https://view.officeapps.live.com/op/view.aspx?src=' + url, '_blank')
      }
    },
    // 判断是图片后缀名
    isImage(url) {
      if (typeof url === 'string') {
        const fileType = url.substring(url.lastIndexOf('.')).toLowerCase()
        return ['.jpg', '.png', '.jpeg', '.gif', '.webp'].includes(fileType)
      }
      return false
    },
    /* 下载附件 */
    downLoad(url, name) {
      var link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
      link.setAttribute('download', name)
      document.body.appendChild(link)
      link.click()
    },
    delFile(file, fileName, index) {
      var ishas = this.fileList.findIndex(f => f.uid === file.uid)
      this.uidsObj[this.showList[index].uid] = false
      if (ishas > -1) {
        this.fileList.splice(ishas, 1)
      } else {
        this.showList.splice(ishas, 1)
      }
      this.$emit('input', this.fileList)
      this.$emit('change', this.fileList)
    },
    closeViewer() {
      this.dialogViewFileImg = false
    },
    parsePercentage(val, status) {
      if (status === 'success') {
        return 100
      }
      if (status === 'exception') {
        return 0
      }
      if (typeof val !== 'number') return 0
      return parseInt(val, 10)
    },
    uploadRequest(option) {
      const self = this
      const file = option.file
      const type = file.type
      const size = file.size
      const pos = file.name.lastIndexOf('.')
      const filename = file.name.substring(0, pos)
      const extendName = file.name.substring(pos + 1)

      var param = new window.FormData()
      param.append('file', file, file.name)
      const { policy, signature, ossaccessKeyId, key, dir, host } = this.policyData
      param.append('policy', policy)
      param.append('signature', signature)
      param.append('ossaccessKeyId', ossaccessKeyId)
      param.append('key', key)
      param.append('dir', dir)
      param.append('host', host)
      axios
        .post(this.action, param, {
          headers: {
            'Content-Type': 'application/json;charset=UTF-8',
            Authorization: this.token
          },
          onUploadProgress(p) {
            self.setShowList(file.uid, 'percentage', 99 * (p.loaded / p.total))
          }
        })
        .then(r => {
          if (r.data.code === 200) {
            this.setShowList(file.uid, 'percentage', 100)
            this.setShowList(file.uid, 'f_status', 'success')
            this.handleFileSuccess({ filename, extendName, size, type, ...r.data }, file)
          } else {
            this.$message.error(r.data.message)
            this.setShowList(file.uid, 'f_status', 'exception')
          }
        })
        .catch(e => {
          this.setShowList(file.uid, 'f_status', 'exception')
          this.$message.error('上传失败')
        })
    },
    // 设置展示列表样式
    setShowList(uid, str, val) {
      var index = this.showList.findIndex(f => f.uid === uid)
      if (index > -1) {
        this.$set(this.showList[index], str, val)
      }
      // 成功
      if (str === 'f_status' && val === 'success') {
        setTimeout(() => {
          this.setShowList(uid, str, '')
        }, 1500)
        return
      }
      // 失败 展示1.5s后 删除
      if (str === 'f_status' && val === 'exception') {
        setTimeout(() => {
          index = this.showList.findIndex(f => f.uid === uid)
          this.showList.splice(index, 1)
        }, 1500)
        return
      }
    },
    async handleBeforeUpLoad(file) {
      var t = file.type.indexOf('image') !== -1
      if (!t) {
        this.$message.error(`只能上传图片！`)
        return false
      }
      this.uidsObj[file.uid] = true
      this.showList = [
        ...this.showList,
        {
          uid: file.uid,
          f_status: 'uploading',
          percentage: 0,
          imgurl: URL.createObjectURL(file),
          isimage: t,
          icon: t ? '' : 'file-file'
        }
      ]
      if (!this.policyData.policy) {
        let data = await this.getpolicy()
        return data
      }
    }
  }
}
</script>
<style lang="scss" scoped>
@import './style/uploadList.scss';
</style>
